package org.yi.fc.config;

import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.ext.jfinal.BeetlRenderFactory;
import org.beetl.ext.tag.HTMLTagSupportWrapper;
import org.yi.fc.controller.admin.content.ContentController;
import org.yi.fc.controller.admin.login.LoginController;
import org.yi.fc.entity.FContent;
import org.yi.fc.entity.FUser;
import org.yi.fc.ext.tag.ForEachTag;
import org.yi.fc.handler.BaseHandler;
import org.yi.fc.interceptor.SessionInterceptor;
import org.yi.fc.utils.FileUtils;
import org.yi.fc.utils.LogUtils;

import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.wall.WallFilter;
import com.google.common.base.Throwables;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.ext.interceptor.SessionInViewInterceptor;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.druid.DruidPlugin;

/**
 * JFinal初始化配置
 * @author qq
 *
 */
public class InitConfig extends JFinalConfig {

	/**
	 * 配置常量
	 */
	@Override
	public void configConstant(Constants me) {
		// 加载数据库配置
		loadPropertyFile("jdbc.properties");
		//加载日志组件
		try {
			LogUtils.load(FileUtils.locateAbsolutePathFromClasspath("logback.xml").getAbsolutePath());
		} catch (Throwable t) {
			throw Throwables.propagate(t);
		}
		
		BeetlRenderFactory brf = new BeetlRenderFactory();
		//注册标签
		GroupTemplate gt = BeetlRenderFactory.groupTemplate;
		gt.registerTag("foreach", ForEachTag.class);
		
		me.setMainRenderFactory(brf);
		
		me.setDevMode(getPropertyToBoolean("devMode", false));
	}

	/**
	 * 配置路由
	 */
	@Override
	public void configRoute(Routes me) {
		//TODO 可拔插插件: 路由做成xml配置， 放到文件夹中， 新增插件时只需在xml中配置好路由即可
		me.add("/admin", LoginController.class);
		me.add("/admin/content", ContentController.class);
	}

	/**
	 * 配置插件
	 */
	@Override
	public void configPlugin(Plugins me) {
		
		DruidPlugin dp=new DruidPlugin(getProperty("jdbc.url"), 
				getProperty("jdbc.username"), getProperty("jdbc.password"),getProperty("jdbc.driverClassName"));
		
		dp.addFilter(new StatFilter());
		
		dp.setInitialSize(getPropertyToInt("db.initialSize", 10));
		dp.setMinIdle(getPropertyToInt("db.minIdle", 10));
		dp.setMaxActive(getPropertyToInt("max.active", 100));
		dp.setMaxWait(getPropertyToInt("db.maxWait", 60000));
		dp.setTimeBetweenEvictionRunsMillis(getPropertyToInt("db.timeBetweenEvictionRunsMillis", 120000));
		dp.setMinEvictableIdleTimeMillis(getPropertyToInt("db.minEvictableIdleTimeMillis", 120000));
		
		WallFilter wall = new WallFilter();
		wall.setDbType(getProperty("db.type"));
		dp.addFilter(wall);
		me.add(dp);
		
		ActiveRecordPlugin activeRecord = new ActiveRecordPlugin(dp);
		activeRecord.setDialect(new MysqlDialect());
		
		//后期开启
//		me.add(new EhCachePlugin());
		
		mapping(activeRecord);
		
		me.add(activeRecord);
		loadExtraPlugins(me);
	}

	/**
	 * 加载插件目录中的插件
	 * @param me
	 */
	private void loadExtraPlugins(Plugins me) {
		// TODO 加载插件目录中的插件
		
	}

	/**
	 * 配置实体-表映射
	 * 以后多了可以考虑做成xml或者annotation
	 * @param activeRecord
	 */
	private void mapping(ActiveRecordPlugin activeRecord) {
		activeRecord.addMapping("f_user", FUser.class)
		.addMapping("f_content", FContent.class);

		
		loadExtraMapping(activeRecord);
	}

	/**
	 * 插件需要单独建立实体类映射文件， 此处按照插件配置文件中的配置进行加载
	 * @param activeRecord
	 */
	private void loadExtraMapping(ActiveRecordPlugin activeRecord) {
		// TODO 加载插件目录中的实体映射
		
	}

	/**
	 * 配置拦截器
	 */
	@Override
	public void configInterceptor(Interceptors me) {
		//判断用户是否登陆
		me.add(new SessionInterceptor());
		//关联beetl的session输出
		me.add(new SessionInViewInterceptor());
		//自动注入
//		me.add(new AutoInjectInterceptor());
	}

	/**
	 * 配置处理器
	 */
	@Override
	public void configHandler(Handlers me) {
		me.add(new BaseHandler());
	}

}
